/*
    jQuery plugin for creating scrollbar without adding dynamically HTML elements.
    Copyright (c) 2010 Keiji Hokamura (Johnnybroccolii)
    This plugin available for use in all personal or commercial projects under both MIT and GPL licenses.
 */

document.onselectstart = function() {
	return false;
};

(function($) {
	var methods = {
		verticalScrollbar: function(settings, self) {
			var data = {
				displayed: false,
				handler: null
			};
			self.data($.scrollbarSetup.DATA, data);
		
		    self.css('position', 'absolute').css('top', 0).parent().css('position', 'absolute');
		    settings.target.css('position', 'absolute').css('top', 0).parent().css('position', 'absolute');
		    
		    function resizeHandler() {
		    	if (settings.target.parent().height() < settings.target.height()) {
		    		if (!settings.barImage) {
		    			self.height(barHeight());
		    		}
		    		if (!data.displayed) {
		    			showBar();
		    		}
			    	var targetTop = parseInt(settings.target.css('top'));
		    		var targetScrollRange = settings.target.height() - settings.target.parent().height();
		    		var scrollRange = self.parent().height() - self.height();
		    		var scrollbarTop = scrollRange * -1 * targetTop / targetScrollRange;
//					alert("Target: " + targetScrollRange + ", scroll: " + scrollRange + ", scroll top: " + scrollbarTop);
					if (scrollbarTop < scrollRange) {
						self.css('top', scrollbarTop);
					}
					else {
						self.css('top', scrollRange);
						settings.target.css('top', -1 * targetScrollRange);
					}
		    	}
		    	else {
		    		if (data.displayed) {
		    			hideBar();
		    		}
		    	}
		    };
		    function dragHandler() {
		    	var scrollLength = self.parent().height() - self.height();
				var targetScrollLength = settings.target.innerHeight() - settings.target.parent().height();
				settings.target.css('top', -1 * parseInt(self.css('top')) / scrollLength * targetScrollLength);
			};
			function showBar() {
	    		self.stop().fadeTo(0, 0).fadeTo(300, 1);
	    		self.parent().show();
	    		data.displayed = true;
			}
			function hideBar() {
	    		settings.target.css('top', 0);
	    		data.displayed = false;
	    		self.stop().fadeTo(300, 0, function() {
	    			$(this).parent().hide();
	    		});
			}
			function barHeight() {
		    	var containerHeight = self.parent().height();
		    	var height = containerHeight - (settings.target.height() - settings.target.parent().height());
		    	return height < $.scrollbarSetup.MINIMUM_HEIGHT ? $.scrollbarSetup.MINIMUM_HEIGHT : height;
			}
			
			if (settings.target.height() > settings.target.parent().height()) {
				if (settings.barImage) {
					resizeHandler();
				}
				else {
					self.height(self.parent().height() - settings.barAnimation.offset);
					showBar();
					self.animate({
						height: barHeight()
					}, settings.barAnimation.duration, settings.barAnimation.easeType, resizeHandler);
				}
			}
			else {
				hideBar();
			}
			
		    $(window).resize(resizeHandler);
		    $(document).mousewheel(function(event, delta) {
		    	var scrollbarTop = parseInt(self.css('top')) + delta * -1;
		    	var maxTop = self.parent().height() - self.height();
		    	scrollbarTop = scrollbarTop < 0 ? 0 :
		    		scrollbarTop > maxTop ? maxTop : scrollbarTop;
		    	self.css('top', scrollbarTop);
		    	dragHandler();
		    });
			
		    data.handler = resizeHandler;
			return self.draggable({
				axis: 'y',
				containment: 'parent',
				drag: dragHandler,
				cursor: 'pointer'
			});
		},
		updateVerticalScrollbar: function(self) {
			var data = self.data($.scrollbarSetup.DATA);
			if (data != null && data.handler != null) {
				data.handler();
			}
		},
		releaseScrollbar: function(self) {
			var data = self.data($.scrollbarSetup.DATA);
			if (data != null && data.handler != null) {
				data.handler = null;
				$(window).unbind('resize', data.handler).unmousewheel();
				return self.draggable('destroy').unbind('mouseenter').unbind('mouseleave');
			}
			else {
				return self;
			}
		}
	};

	$.fn.scrollbarSetup = function(settings) {
	    settings = $.extend({
	    	action: $.scrollbarSetup.SETUP,
	    	target: null,
    		barAnimation: {
	    		easeType: 'easeOutCirc',
	    		duration: 600,
	    		offset: 10
    		},
    		barImage: false
	    }, settings);
	    
	    switch (settings.action) {
	    	case $.scrollbarSetup.SETUP:
	    		methods.verticalScrollbar(settings, this);
	    		break;
	    	case $.scrollbarSetup.UPDATE:
	    		methods.updateVerticalScrollbar(this);
	    		break;
	    	case $.scrollbarSetup.RELEASE:
	    		methods.releaseScrollbar(this);
	    		break;
	    }
	    return this;
	};
	
	$.scrollbarSetup = {
		DATA: 'scrollbar-setup',
		SETUP: 'setup',
		UPDATE: 'update',
		RELEASE: 'release',
		MINIMUM_HEIGHT: 200
	};

})(jQuery);